# -*- coding: UTF-8 -*-
# @Project ：VehicleDimensionMeasurementSystem 
# @File    ：report_module.py
# @IDE     ：PyCharm 
# @Date    ：2024/6/16 下午8:49
import json
import os
import shutil

from source.modules import app_settings
from PIL import Image as PILImage
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import SimpleDocTemplate, Paragraph, Image, Table, TableStyle, Spacer
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT

# 注册字体
pdfmetrics.registerFont(TTFont('SimSun', 'simhei.ttf'))


class Graphs:
    @staticmethod
    def draw_title():
        title_style = ParagraphStyle(
            name="title",
            fontName="SimSun",
            fontSize=24,
            leading=10,
            alignment=TA_CENTER,
            textColor=colors.HexColor('#130c0e'),
            spaceAfter=20,
        )
        title = Paragraph('汽车外廓尺寸检测仪检测报告', title_style)
        return title

    @staticmethod
    def draw_company_name():
        title_style = ParagraphStyle(
            name="company_name",
            fontName="SimSun",
            fontSize=12,
            alignment=TA_LEFT,
            textColor=colors.HexColor('#130c0e'),
            spaceAfter=8,
        )
        company_name = Paragraph('检测单位名称：', title_style)
        return company_name

    @staticmethod
    def draw_table(*args):  # 画表1
        col_width = 29  # 设置表的列宽为20
        row_height = 24  # 设置行高为36
        styles = [
            ('FONTNAME', (0, 0), (-1, -1), 'SimSun'),  # 设置字体
            ('FONTSIZE', (0, 0), (-1, -1), 12),  # 字体大小
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 水平居中
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 垂直居中
            ('GRID', (0, 0), (-1, -1), 0.25, colors.black),  # 设置边框， 0.25边框厚度， colors.black边框颜色
            # --------第流水号行----------
            ('SPAN', (0, 0), (1, 0)),  # 合并单元格, 合并第一行的0~4列， 流水号
            ('SPAN', (2, 0), (8, 0)),
            ('SPAN', (9, 0), (11, 0)),
            ('SPAN', (12, 0), (-1, 0)),
            # --------第二号牌号码行----------
            ('SPAN', (0, 1), (1, 1)),
            ('SPAN', (2, 1), (8, 1)),
            ('SPAN', (9, 1), (11, 1)),
            ('SPAN', (12, 1), (-1, 1)),
            # --------第三号牌种类行----------
            ('SPAN', (0, 2), (1, 2)),
            ('SPAN', (2, 2), (8, 2)),
            ('SPAN', (9, 2), (11, 2)),
            ('SPAN', (12, 2), (-1, 2)),
            # --------第四检测时间行----------
            ('SPAN', (0, 3), (1, 3)),
            ('SPAN', (2, 3), (8, 3)),
            ('SPAN', (9, 3), (11, 3)),
            ('SPAN', (12, 3), (-1, 3)),
            # --------第五检测项目行----------
            ('SPAN', (0, 4), (1, 4)),
            ('SPAN', (2, 4), (4, 4)),
            ('SPAN', (5, 4), (7, 4)),
            ('SPAN', (8, 4), (9, 4)),
            ('SPAN', (10, 4), (11, 4)),
            ('SPAN', (12, 4), (16, 4)),
            ('SPAN', (17, 4), (-1, 4)),
            # --------第6整车长行----------
            ('SPAN', (0, 5), (1, 5)),
            ('SPAN', (2, 5), (4, 5)),
            ('SPAN', (5, 5), (7, 5)),
            ('SPAN', (8, 5), (9, 5)),
            ('SPAN', (10, 5), (11, 5)),
            ('SPAN', (12, 5), (16, 5)),
            ('SPAN', (17, 5), (-1, 5)),
            # --------第7整车宽行----------
            ('SPAN', (0, 6), (1, 6)),
            ('SPAN', (2, 6), (4, 6)),
            ('SPAN', (5, 6), (7, 6)),
            ('SPAN', (8, 6), (9, 6)),
            ('SPAN', (10, 6), (11, 6)),
            ('SPAN', (12, 6), (16, 6)),
            ('SPAN', (17, 6), (-1, 6)),
            # --------第8整车高行----------
            ('SPAN', (0, 7), (1, 7)),
            ('SPAN', (2, 7), (4, 7)),
            ('SPAN', (5, 7), (7, 7)),
            ('SPAN', (8, 7), (9, 7)),
            ('SPAN', (10, 7), (11, 7)),
            ('SPAN', (12, 7), (16, 7)),
            ('SPAN', (17, 7), (-1, 7)),
            # --------第9轴距行----------
            ('SPAN', (0, 8), (1, 8)),
            ('SPAN', (2, 8), (4, 8)),
            ('SPAN', (5, 8), (7, 8)),
            ('SPAN', (8, 8), (9, 8)),
            ('SPAN', (10, 8), (11, 8)),
            ('SPAN', (12, 8), (16, 8)),
            ('SPAN', (17, 8), (-1, 8)),
            # --------第10行 栏板深度----------
            ('SPAN', (0, 9), (1, 9)),
            ('SPAN', (2, 9), (4, 9)),
            ('SPAN', (5, 9), (7, 9)),
            ('SPAN', (8, 9), (9, 9)),
            ('SPAN', (10, 9), (11, 9)),
            ('SPAN', (12, 9), (16, 9)),
            ('SPAN', (17, 9), (-1, 9)),

            # --------第11行 整备质量----------
            ('SPAN', (0, 10), (1, 10)),
            ('SPAN', (2, 10), (4, 10)),
            ('SPAN', (5, 10), (7, 10)),
            ('SPAN', (8, 10), (9, 10)),
            ('SPAN', (10, 10), (11, 10)),
            ('SPAN', (12, 10), (16, 10)),
            ('SPAN', (17, 10), (-1, 10)),
            # --------第12~18行 图片----------
            ('SPAN', (0, 11), (9, 18)),
            ('SPAN', (10, 11), (-1, 18)),
            # --------第19~26行 图片----------
            ('SPAN', (0, 19), (9, 26)),
            ('SPAN', (10, 19), (-1, 26)),
            # --------第27行----------
            ('SPAN', (0, 27), (1, 28)),
            ('SPAN', (2, 27), (4, 28)),
            ('SPAN', (5, 27), (6, 28)),
            ('SPAN', (7, 27), (9, 28)),
            ('SPAN', (10, 27), (11, 28)),
            ('SPAN', (12, 27), (-1, 28)),
        ]  # 设置表的样式
        table = Table(*args, colWidths=col_width, rowHeights=row_height)
        table.setStyle(TableStyle(styles))
        return table

    @staticmethod
    def draw_national_norm():
        """依据什么标准在执行"""
        title_style = ParagraphStyle(
            name="company_name",
            fontName="SimSun",
            fontSize=10,
            leading=10,
            alignment=TA_LEFT,
            textColor=colors.HexColor('#130c0e'),
            spaceFront=10,
        )
        national_norm_text = Paragraph(
            '依据《GB 38900-2020 机动车安全检验项目和方法》\n    《GB 1589-2016 汽车、挂车及汽车列车外廓尺寸、轴荷及质量限值》',
            title_style)
        return national_norm_text


def build_pdf(vehicle_info_object, measure_record, file_name):
    contents = list()

    # 判定要显示合格与不合格需要做处理
    def judge_show(filed_judge):
        # print(filed_judge)
        # show_filed = filed_judge if filed_judge else "-"
        if filed_judge is False:
            return '不合格'
        elif filed_judge is True:
            return '合格'
        else:
            return '-'

    data = [('流水号', '',
             f'{vehicle_info_object.serial_number}', '', '', '', '', '', '',
             '车辆识别代号', '', '',
             f'{vehicle_info_object.vin}', '', '', '', '', ''),
            ('号牌号码', '',
             f'{vehicle_info_object.plate_number}', '', '', '', '', '', '',
             '检验类别', '', '',
             f'{measure_record.inspection_category.inspection_category}', '', '', '', '', '', ''),
            ('号牌种类', '',
             f'{vehicle_info_object.plate_type.plate_type}', '', '', '', '', '', '',
             '车辆类型', '', '',
             f'{vehicle_info_object.vehicle_type.vehicle_type}', '', '', '', '', '', ''),
            ('检测时间', '',
             f'{measure_record.measure_time}', '', '', '', '', '', '',
             '检验次数', '', '',
             f'{measure_record.inspection_count}', '', '', '', '', '', ''),
            ('检测项目', '', '标准数据', '', '', '检测数据', '', '', '差值', '', '百分比', '', '标准限值', '', '', '',
             '', '判定', ''),
            ('整车长', '',
             f'{vehicle_info_object.standard_length if vehicle_info_object.standard_length else "-"}', '', '',
             f'{measure_record.measure_length if measure_record.measure_length else "-"}', '', '',
             f'{measure_record.length_diff if measure_record.length_diff else "-"}', '',
             f'{measure_record.length_per if measure_record.length_per else "-"}', '',
             '', '', '', '', '',
             f'{judge_show(measure_record.length_judge)}', ''),
            ('整车宽', '',
             f'{vehicle_info_object.standard_width if vehicle_info_object.standard_width else "-"}', '', '',
             f'{measure_record.measure_width if measure_record.measure_width else "-"}', '', '',
             f'{measure_record.width_diff if measure_record.width_diff else "-"}', '',
             f'{measure_record.width_per if measure_record.width_per else "-"}', '',
             '', '', '', '', '',
             f'{judge_show(measure_record.width_judge)}', ''),
            ('整车高', '',
             f'{vehicle_info_object.standard_height if vehicle_info_object.standard_height else "-"}', '', '',
             f'{measure_record.measure_height if measure_record.measure_height else "-"}', '', '',
             f'{measure_record.height_diff if measure_record.height_diff else "-"}', '',
             f'{measure_record.height_per if measure_record.height_per else "-"}', '',
             '', '', '', '', '',
             f'{judge_show(measure_record.height_judge)}', ''),
            ('轴距', '',
             f'{vehicle_info_object.standard_wheelbase if vehicle_info_object.standard_wheelbase else "-"}', '', '',
             f'{measure_record.measure_wheelbase if measure_record.measure_wheelbase else "-"}', '', '',
             f'{measure_record.wheelbase_diff if measure_record.wheelbase_diff else "-"}', '',
             f'{measure_record.wheelbase_per if measure_record.wheelbase_per else "-"}',
             '', '', '', '', '', '',
             f'{judge_show(measure_record.wheelbase_judge)}', ''),
            ('栏板深度', '',
             f'{vehicle_info_object.standard_fence_depth if vehicle_info_object.standard_fence_depth else "-"}', '', '',
             f'{measure_record.measure_fence_depth if measure_record.measure_fence_depth else "-"}', '', '',
             f'{measure_record.fence_depth_diff if measure_record.fence_depth_diff else "-"}', '',
             f'{measure_record.fence_depth_per if measure_record.fence_depth_per else "-"}',
             '', '', '', '', '', '',
             f'{judge_show(measure_record.fence_depth_judge)}', ''),
            ('整备质量', '',
             f'{vehicle_info_object.standard_curb_weigh if vehicle_info_object.standard_curb_weigh else "-"}', '', '',
             f'{measure_record.measure_curb_weigh if measure_record.measure_curb_weigh else "-"}', '', '',
             f'{measure_record.curb_weigh_diff if measure_record.curb_weigh_diff else "-"}', '',
             f'{measure_record.curb_weigh_per if measure_record.curb_weigh_per else "-"}',
             '', '', '', '', '', '',
             f'{judge_show(measure_record.curb_weigh_judge)}', ''),
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
            (
                '检验员', '', '', '', '', '引车员', '', '', '', '', '检测结果', '',
                f'{judge_show(measure_record.total_judge)}', '',
                '',
                '', '', ''),
            ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''),
            ]
    contents.append(Graphs.draw_title())
    contents.append(Graphs.draw_company_name())
    picture_path_dict = json.loads(measure_record.picture_path)  # 获取图片路径，json字符串需要进行解析
    head_img = Image(picture_scaling(picture_path_dict.get('head_picture_path')[0], 'head'))
    after_img = Image(picture_scaling(picture_path_dict.get('after_picture_path')[0], 'after'))
    side_img = Image(picture_scaling(picture_path_dict.get('side_picture_path')[0], 'side'))
    top_img = Image(picture_scaling(picture_path_dict.get('top_picture_path')[0], 'top'))
    data[11][0] = head_img
    data[11][10] = side_img
    data[19][0] = after_img
    data[19][10] = top_img
    table = Graphs.draw_table(data)
    contents.append(table)
    contents.append(Graphs.draw_national_norm())
    doc = SimpleDocTemplate(file_name, pagesize=A4, topMargin=20, leftMargin=20, rightMargin=20, bottomMargin=20)
    doc.build(contents)
    # 删除目录下的文件
    shutil.rmtree(os.path.join(app_settings.PICTURE_DIR, 'temp_file'))


def picture_scaling(image_path, position):
    """图片的缩放功能"""
    image = PILImage.open(image_path)
    # 获取图片的原始尺寸
    original_width, original_height = image.size

    # 设置目标尺寸
    if position == 'head' or position == 'after':  # 车头车尾照片
        target_width, target_height = 290, 240
    else:  # 模型图摘牌
        target_width, target_height = 261, 216

    # 设置缩放比例
    width_ratio = target_width / original_width
    height_ratio = target_height / original_height
    scale_ratio = min(width_ratio, height_ratio)

    # 计算新的尺寸
    new_width = int(original_width * scale_ratio)
    new_height = int(original_height * scale_ratio)

    # 缩放图片，使用高质量的重采样算法
    if scale_ratio < 1:  # 如果是缩小图像
        resized_image = image.resize((new_width, new_height), PILImage.LANCZOS)
    else:  # 如果是放大图像
        resized_image = image.resize((new_width, new_height), PILImage.BICUBIC)
    # 保存图片到临时文件，需要提供文件名而不是文件对象
    if not os.path.exists(os.path.join(app_settings.PICTURE_DIR, 'temp_file')):
        os.makedirs(os.path.join(app_settings.PICTURE_DIR, 'temp_file'))
    temp_file_path = os.path.join(app_settings.PICTURE_DIR, 'temp_file', f'{position}.jpg')
    resized_image.save(temp_file_path, format='JPEG', quality=95)
    return temp_file_path
